package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/dish")
public class DishController {

    @Autowired
    private DishService dishService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private DishFlavorService dishFlavorService;

    /**
     *新增菜品
     */
    @PostMapping    //接收的json数据，要用@RequestBody
    public R<String> save(@RequestBody DishDto dishDto)   { //为什么叫save？
        dishService.saveWithFlavor(dishDto);
        return R.success("新增菜品成功");

    }//要操作两张表，要在Service中加方法

    /**
     * 菜品信息分页查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */

    @GetMapping("page")
    public R<Page> page(int page,int pageSize,String name){//菜品管理左上角搜索时 输入的名称
        //构造分页构造器
        Page<Dish> pageInfo =new Page(page,pageSize);
        Page<DishDto> dishDtoPage =new Page<>();//此时dishDtoPage中的属性并没有赋值，
        //但是pageInfo经过dishServic.page查询后 有值；此时经过对象的拷贝，把pageInfo中的属性值对应的拷到dishDtoPage中



        //条件构造器
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();

        //添加过滤条件
        queryWrapper.like(name!=null,Dish::getName,name);
        //like是模糊查询，第一个是判断不为空时，

        //添加排序条件
        queryWrapper.orderByDesc(Dish::getUpdateTime);

        //执行分页查询
        dishService.page(pageInfo,queryWrapper);

        //Dish 中存的是分类id，而页面上要的是 分类的名称

        //对象拷贝
        BeanUtils.copyProperties(pageInfo,dishDtoPage,"records");
        //前面那个拷贝到后面那个，但是不拷贝 records,因其这个List集合是 页面上展示出来的数据

        List<Dish> records = pageInfo.getRecords();  //p62
        List<DishDto> list =records.stream().map((item) ->{ //基于records集合来处理得到流对象，而map就是把每个元素拿出来，通过Lambda表达式处理
            DishDto dishDto = new DishDto();
            //创建新的dto对象，且通过拷贝将基本属性拷进去
            BeanUtils.copyProperties(item,dishDto);

            Long categoryId =item.getCategoryId();//得到分类id（这个Dish中就有)
            //根据id查询分类对象
            Category category =categoryService.getById(categoryId);//查数据库
            if(category != null){ //之前导入数据可能有问题，导致查询数据时可能有问题没查到
                String categoryName =category.getName();//获取分类名称并给dto对象设置分类名称
                dishDto.setCategoryName(categoryName);//（Category类中有categoryId 和 categoryName
            }

            return dishDto;  //为什么要返回dto对象啊?
        }).collect(Collectors.toList());
    //收集dto对象,转成集合       //这个遍历records对象，并在此过程中 完成操作

        dishDtoPage.setRecords(list);//再将list对象赋给dishDtpPage的Records属性（这个records属性在哪？
        //Page<DishDto> dishDtoPage =new Page<>();  前面这个怎么理解？
        return R.success(dishDtoPage);

    }

    /**
     * 根据id查询菜品信息和对应的口味信息
     * @param id
     * @return
     */
    @GetMapping("/{id}")//id 在请求url中,要用{} 和 @PathVariable
    //这个DishDto看你要返回啥，这里要返回基本数据外，还要在页面显示 口味
    public R<DishDto>  get (@PathVariable Long id){ //<> 中的类型由前端页面决定，方法名无所谓（那那些有所谓？
//        private DishService dishService1;这个导入一般在方法外面
        DishDto dishDto = dishService.getByIdWithFlavor(id);
        return  R.success(dishDto);


    }//只用dishService查数据库不行，只查询了菜品表，这里要查两张表


    @PutMapping
    public R<String> update(@RequestBody DishDto dishDto){

        dishService.updateWithFlavor(dishDto);  //这个时更新表中数据，不需要返回什么，更不需要赋值给对象

        return R.success("新增菜品成功");
    }

    /**
     * 根据条件查对应的菜品数据
     */
//    @GetMapping("/list")
//    public R<List<Dish>> list(Dish dish){ //可以用 Long categoryId 但是 用 通用性更高的,当传其他参数的请求 依旧可以接收
//
//        //构造查询条件对象
//        LambdaQueryWrapper<Dish> queryWrapper =new LambdaQueryWrapper<>();
//        queryWrapper.eq( dish.getCategoryId() != null,Dish::getCategoryId,dish.getCategoryId());
//        //添加条件，status 为1 则为起售
//        queryWrapper.eq(Dish::getStatus,1);//查询为1的status
//
//        //添加排序条件,根据菜品里的sort来排序
//        queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
//
//        List<Dish> list = dishService.list(queryWrapper);
//        return R.success(list);
//    }////菜品展示之前的代码

    @GetMapping("/list")
    public R<List<DishDto>> list(Dish dish){ //可以用 Long categoryId 但是 用 通用性更高的,当传其他参数的请求 依旧可以接收

        //构造查询条件对象
        LambdaQueryWrapper<Dish> queryWrapper =new LambdaQueryWrapper<>();
        queryWrapper.eq( dish.getCategoryId() != null,Dish::getCategoryId,dish.getCategoryId());
        //添加条件，status 为1 则为起售
        queryWrapper.eq(Dish::getStatus,1);//查询为1的status

        //添加排序条件,根据菜品里的sort来排序
        queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);

        List<Dish> list = dishService.list(queryWrapper);

        List<DishDto> dishDtoList = list.stream().map((item) ->{
            DishDto dishDto =new DishDto();
            BeanUtils.copyProperties(item,dishDto);
            Long categoryId =item.getCategoryId();//分类Id
            //根据id查询分类对象
            Category category = categoryService.getById(categoryId);
            if(category != null){
                String categoryName =category.getName();
                dishDto.setCategoryName(categoryName);

            }

            //当前菜品id
            Long dishId = item.getId();
            LambdaQueryWrapper<DishFlavor> lambdaQueryWrapper=new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(DishFlavor::getDishId,dishId);
            //SQL：select * from dish_flavor where dish_id = ?
            List<DishFlavor> dishFlavorList = dishFlavorService.list(lambdaQueryWrapper);
            dishDto.setFlavors(dishFlavorList);
            return dishDto;

        }).collect(Collectors.toList());

        return R.success(dishDtoList);
    }

}
